import java.io.*;
import java.net.Socket;
import java.util.HashMap;
import java.util.Map;

public class ChatChannel implements Runnable {
    private static Map<String, ObjectOutputStream> allMap = new HashMap<>();
    private Socket socket;

    public ChatChannel(Socket socket) {
        this.socket = socket;
    }

    public void run() {
        String name = null;
        ObjectInputStream ois = null;
        ObjectOutputStream oos = null;

        try {
            // 获取输入输出流
            InputStream is = socket.getInputStream();
            ois = new ObjectInputStream(is);
            OutputStream os = socket.getOutputStream();
            oos = new ObjectOutputStream(os);

            // 接收客户端发送的用户名
            name = (String) ois.readObject();
            // 将用户加入全局映射表
            synchronized (allMap) {
                allMap.put(name, oos);
            }

            // 发送欢迎信息
            oos.writeObject(name + "，您好!欢迎您进入聊天室");

            // 广播用户上线消息
            System.out.println(name + "进入聊天室");
            sendToAll("系统信息：" + name + "进入聊天室");

            // 持续接收消息并广播
            while (true) {
                String msg = (String) ois.readObject();
                if (msg.indexOf('@') == 0) {
                    int end = msg.indexOf('#');
                    String secretName = msg.substring(1, end);
                    String secretmsg = msg.substring(end + 1);
                    sendToUser(secretName, name + "悄悄地对您说：" + secretmsg); // 私聊
                    System.out.println(name + "悄悄地对" + secretName + "说：" + secretmsg);
                } else {
                    System.out.println(name + "说：" + msg);
                    sendToAll(name + "说：" + msg);
                }
            }

        } catch (IOException | ClassNotFoundException e) {
            // 用户断开连接
            if (name != null) {
                synchronized (allMap) {
                    allMap.remove(name);
                }
                System.out.println(name + "离开聊天室");
                sendToAll("系统信息：" + name + "离开聊天室");
            }
        } finally {
            try {
                if (ois != null) ois.close();
                if (oos != null) oos.close();
                if (socket != null) socket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    // 群发消息给所有人
    private void sendToAll(String message) {
        synchronized (allMap) {
            for (ObjectOutputStream oos : allMap.values()) {
                try {
                    oos.writeObject(message);
                    oos.flush(); // 确保消息及时发送
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    // 私发消息给指定用户
    private void sendToUser(String username, String message) {
        synchronized (allMap) {
            ObjectOutputStream oos = allMap.get(username);
            if (oos != null) {
                try {
                    oos.writeObject(message);
                    oos.flush();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
